import numpy as np
import matplotlib.pyplot as plt

def dydt(t, y):
    return -2 * y

def euler_method(dydt, t0, y0, t_end, h):
    t_values = np.arange(t0, t_end + h, h)  
    y_values = np.zeros(len(t_values))  
    y_values[0] = y0  

    for i in range(1, len(t_values)):
        t = y_values[i - 1] + h * dydt(t_values[i - 1], y_values[i - 1])
        y_values[i] = y_values[i - 1] + h / 2 * (dydt(t_values[i - 1], y_values[i - 1]) + dydt(t_values[i - 1], t))

    return t_values, y_values

y0 = 1
t0 = 0
t_end = 5
h = 0.1 

t_values, y_euler = euler_method(dydt, t0, y0, t_end, h)

def analytical_solution(t):
    return np.exp(-2 * t)

y_analytical = analytical_solution(t_values)

error = np.abs(y_euler - y_analytical)

plt.figure(figsize=(10, 8))  

plt.subplot(2, 1, 1) 
plt.plot(t_values, y_euler, label='Euler Method (Numerical)', linestyle='--')
plt.plot(t_values, y_analytical, label='Analytical Solution', linestyle='-')
plt.xlabel('t')
plt.ylabel('y(t)')
plt.title('Euler Method vs Analytical Solution')
plt.legend()

plt.subplot(2, 1, 2) 
plt.plot(t_values, error, label='Error', color='red')
plt.xlabel('t')
plt.ylabel('Error')
plt.title('Error between Euler Method and Analytical Solution')
plt.legend()

plt.tight_layout()
plt.show()